package com.anolesoft.yr.mbus.fin.service.impl;

import com.anolesoft.yr.exception.ServiceException;
import com.anolesoft.yr.mbus.fin.dto.FinBillingApplyDTO;
import com.anolesoft.yr.mbus.fin.entity.FinBillingApplyDO;
import com.anolesoft.yr.mbus.fin.mapper.FinBillingApplyMapper;
import com.anolesoft.yr.mbus.fin.service.FinBillingApplyService;
import com.anolesoft.yr.util.CommonUtils;
import com.anolesoft.yr.util.PageData;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author zhj
 * @date 2020/8/12 16:12
 */
@Service("finBillingApplyServiceImpl")
public class FinBillingApplyServiceImpl implements FinBillingApplyService {
    @Autowired
    private FinBillingApplyMapper finBillingApplyMapper;

    @Transactional
    @Override
    public int create(FinBillingApplyDTO finBillingApplyDTO) {
        checkUnique(finBillingApplyDTO,false);
        return finBillingApplyMapper.insert(FinBillingApplyDO.builder()
                .objuid(finBillingApplyDTO.getObjuid())
                .invoiceState(finBillingApplyDTO.getInvoiceState())
                .contractCode(finBillingApplyDTO.getContractCode())
                .billingCode(finBillingApplyDTO.getBillingCode())
                .factoryCode(finBillingApplyDTO.getFactoryCode())
                .modifyTime(finBillingApplyDTO.getModifyTime())
                .remark(finBillingApplyDTO.getRemark())
                .modifyUserUid(finBillingApplyDTO.getModifyUserUid())
                .deleteFlag(finBillingApplyDTO.getDeleteFlag())
                .createUserUid(finBillingApplyDTO.getCreateUserUid())
                .createTime(finBillingApplyDTO.getCreateTime())
                .amount(finBillingApplyDTO.getAmount())
                .build());
    }
    private void checkUnique(FinBillingApplyDTO finBillingApply, Boolean isModify){
        String billingCode = finBillingApply.getBillingCode();
        String contractCode = finBillingApply.getContractCode();
        if (isModify) {
            if (finBillingApplyMapper.checkUniqueForContractCodeUpdate(contractCode,finBillingApply.getObjuid()) > 0) {
                throw new ServiceException("合同号存在重复");
            }
            if (finBillingApplyMapper.checkUniqueForBillingCodeUpdate(billingCode,finBillingApply.getObjuid()) > 0) {
                throw new ServiceException("申请单编号存在重复");
            }
        }else {
            if (finBillingApplyMapper.checkUniqueForContractCode(contractCode) > 0) {
                throw new ServiceException("合同号存在重复");
            }
            if (finBillingApplyMapper.checkUniqueForBillingCode(billingCode) > 0) {
                throw new ServiceException("申请单编号存在重复");
            }
        }
    }

    @Transactional
    @Override
    public int modify(FinBillingApplyDTO finBillingApplyDTO) {
        checkUnique(finBillingApplyDTO, true);
        FinBillingApplyDO finBillingApplyDO = finBillingApplyMapper.selectOneById(finBillingApplyDTO.getObjuid());
        if (finBillingApplyDO==null) {
            finBillingApplyDO = FinBillingApplyDO.builder().build();
        }
        finBillingApplyDO.setObjuid(finBillingApplyDTO.getObjuid());
        finBillingApplyDO.setInvoiceState(finBillingApplyDTO.getInvoiceState());
        finBillingApplyDO.setContractCode(finBillingApplyDTO.getContractCode());
        finBillingApplyDO.setBillingCode(finBillingApplyDTO.getBillingCode());
        finBillingApplyDO.setFactoryCode(finBillingApplyDTO.getFactoryCode());
        finBillingApplyDO.setModifyTime(finBillingApplyDTO.getModifyTime());
        finBillingApplyDO.setRemark(finBillingApplyDTO.getRemark());
        finBillingApplyDO.setModifyUserUid(finBillingApplyDTO.getModifyUserUid());
        finBillingApplyDO.setDeleteFlag(finBillingApplyDTO.getDeleteFlag());
        finBillingApplyDO.setCreateUserUid(finBillingApplyDTO.getCreateUserUid());
        finBillingApplyDO.setCreateTime(finBillingApplyDTO.getCreateTime());
        finBillingApplyDO.setAmount(finBillingApplyDTO.getAmount());
        return finBillingApplyMapper.update(finBillingApplyDO);
    }

    @Transactional
    @Override
    public int remove(String id) {
        return finBillingApplyMapper.delete(id);
    }

    @Override
    public int removeBatch(List<String> ids) {
        int res = 0;
        for (String id : ids) {
            res += finBillingApplyMapper.delete(id);
        }
        return res;
    }

    @Override
    public List<FinBillingApplyDTO> selectAll() {
        return finBillingApplyMapper.selectAll().stream().map(t -> do2dto(t)).collect(Collectors.toList());
    }

    private FinBillingApplyDTO do2dto(FinBillingApplyDO t) {
        return FinBillingApplyDTO.builder()
                .objuid(t.getObjuid())
                .invoiceState(t.getInvoiceState())
                .contractCode(t.getContractCode())
                .billingCode(t.getBillingCode())
                .factoryCode(t.getFactoryCode())
                .modifyTime(t.getModifyTime())
                .remark(t.getRemark())
                .modifyUserUid(t.getModifyUserUid())
                .deleteFlag(t.getDeleteFlag())
                .createUserUid(t.getCreateUserUid())
                .createTime(t.getCreateTime())
                .amount(t.getAmount())
                .build();
    }

    @Override
    public PageData<List<FinBillingApplyDTO>> selectAll(Integer limit, Integer curr) {
        Page<FinBillingApplyDO> page = new Page<>(curr, limit);
        List<FinBillingApplyDO> finBillingApplyDOs = finBillingApplyMapper.selectPageAll(page);
        List<FinBillingApplyDTO> finBillingApplyDTOs = finBillingApplyDOs.stream().map(t -> do2dto(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), finBillingApplyDTOs);
    }

    @Override
    public Optional<FinBillingApplyDTO> selectOneById(String id) {
        FinBillingApplyDO finBillingApplyDO = finBillingApplyMapper.selectOneById(id);
        if (finBillingApplyDO != null) {
            return Optional.of(do2dto(finBillingApplyDO));
        }
        return Optional.empty();
    }

    @Override
    public List<FinBillingApplyDTO> selectList(FinBillingApplyDTO finBillingApplyDTO) {
        FinBillingApplyDO finBillingApplyDO = buildCondition(finBillingApplyDTO);
        return finBillingApplyMapper.selectList(finBillingApplyDO).stream().map(t -> do2dto(t)).collect(Collectors.toList());
    }

    private FinBillingApplyDO buildCondition(FinBillingApplyDTO finBillingApplyDTO) {
        return FinBillingApplyDO.builder()
                .factoryCode(CommonUtils.stringNull(finBillingApplyDTO.getFactoryCode()))
                .objuid(CommonUtils.stringNull(finBillingApplyDTO.getObjuid()))
                .billingCode(CommonUtils.stringNull(finBillingApplyDTO.getBillingCode()))
                .contractCode(CommonUtils.stringNull(finBillingApplyDTO.getContractCode()))
                .invoiceState(CommonUtils.stringNull(finBillingApplyDTO.getInvoiceState()))
                .build();
    }

    @Override
    public PageData<List<FinBillingApplyDTO>> selectList(FinBillingApplyDTO finBillingApplyDTO, Integer limit, Integer curr) {
        FinBillingApplyDO finBillingApplyDO = buildCondition(finBillingApplyDTO);
        Page<FinBillingApplyDO> page = new Page<>(curr, limit);
        List<FinBillingApplyDO> finBillingApplyDOS = finBillingApplyMapper.selectPageList(finBillingApplyDO, page);
        List<FinBillingApplyDTO> finBillingApplyDTOS = finBillingApplyDOS.stream().map(t -> do2dto(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), finBillingApplyDTOS);
    }

    @Override
    public PageData<List<FinBillingApplyDTO>> selectComboxList(FinBillingApplyDTO finBillingApplyDTO, Integer limit, Integer curr) {
        FinBillingApplyDO finBillingApplyDO = buildCondition(finBillingApplyDTO);
        Page<FinBillingApplyDO> page = new Page<>(curr, limit);
        List<FinBillingApplyDO> finBillingApplyDOS = finBillingApplyMapper.selectComboxList(finBillingApplyDO, page);
        List<FinBillingApplyDTO> finBillingApplyDTOS = finBillingApplyDOS.stream().map(t -> do2dto(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), finBillingApplyDTOS);
    }
}
